﻿using System.ComponentModel;
using System.Drawing.Drawing2D;
using Tetris.Game.ControlsBase.Common;

namespace Tetris.Game.ControlsBase
{
    [ToolboxItem(true)]
    public unsafe class BlockControl : Control, IGameProperty, ICloneable
    {
        public BlockControl()
        {
            SetStyle(
                ControlStyles.ResizeRedraw
                | ControlStyles.DoubleBuffer
                | ControlStyles.UserPaint
                | ControlStyles.AllPaintingInWmPaint
                | ControlStyles.SupportsTransparentBackColor,
                true
                );
            Size = new Size(36, 36);
            Margin = new Padding(0, 0, 0, 0);
            Padding = new Padding(0, 0, 0, 0);
            BackColor = Color.Transparent;
            IsMove = true;
            Id = Guid.NewGuid().ToString();
        }
        private ShapeType _shapeType = ShapeType.O;
        [Description("形状类型"), Category("TF.Game"), Browsable(true)]
        [DefaultValue(ShapeType.O)]
        public ShapeType TetrisShapeType
        {
            get { return _shapeType; }
            set
            {
                _shapeType = value;
                TetrisShapeColor = _shapeType.GetShapeColor();
            }
        }
        private ShapeColor _shapeColor = ShapeTypeEx.OShapeColor;
        [Description("形状颜色"), Category("TF.Game"), Browsable(true)]
        [DefaultValue(typeof(ShapeColor))]
        public ShapeColor TetrisShapeColor
        {
            get { return _shapeColor; }
            set
            {
                _shapeColor = value;
                this.Invalidate();
            }
        }
        private int _shapePadding = 0;
        [Description("小方框内边距"), Category("TF.Game"), Browsable(true)]
        [DefaultValue(0)]
        public int ShapePadding
        {
            get { return _shapePadding; }
            set
            {
                _shapePadding = value;
                this.Invalidate();
            }
        }
        private int _trapezoidWidth = 8;
        [Description("梯形宽"), Category("TF.Game"), Browsable(true)]
        [DefaultValue(8)]
        public int TrapezoidWidth
        {
            get { return _trapezoidWidth; }
            set
            {
                _trapezoidWidth = value;
                this.Invalidate();
            }
        }

        [Browsable(false)]
        public bool IsMove { get; set; }
        [Browsable(false)]
        public string Id { get; set; }
        private int _positionX;
        [Browsable(false)]
        public int PositionX
        {
            get { return _positionX; }
            set
            {
                _lastPositionX = _positionX;
                _positionX = value;

            }
        }
        private int _positionY;
        [Browsable(false)]
        public int PositionY
        {
            get { return _positionY; }
            set
            {
                _lastPositionY = _positionY;
                _positionY = value;
            }
        }
        [Browsable(false)]
        public Point GetCurPosition
        {
            get
            {
                return new Point(PositionX, PositionY);
            }
        }
        private int _lastPositionX;
        [Browsable(false)]
        public int GetLastPositionX
        {
            get { return _lastPositionX; }
        }
        private int _lastPositionY;
        [Browsable(false)]
        public int GetLastPositionY
        {
            get { return _lastPositionY; }
        }
        [Browsable(false)]
        public Point GetLastPosition
        {
            get
            {
                return new Point(GetLastPositionX, GetLastPositionY);
            }
        }
        public bool IsSamePosition
        {
            get
            {
                return GetCurPosition == GetLastPosition;
            }
        }
        [Browsable(false)]
        public string GroupId { get; set; }
        public void UpdateLocation()
        {
            this.Location = new Point(PositionX * Width, PositionY * Height);
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.CompositingQuality= CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            PaintBlock(g, 0, 0, Size.Width, Size.Height);

        }

        protected virtual void PaintBlock(Graphics g, int x, int y, int width, int height)
        {
            using Pen pen = new Pen(TetrisShapeColor.FrameTrapezoidColor, 2);

            // 外正方形
            Rectangle rect = new Rectangle(x, y, width, height);
            using (SolidBrush brush = new SolidBrush(TetrisShapeColor.OuterColor))
            {
                g.FillRectangle(brush, rect);
            }

            // 上
            Point[] points = new Point[4];
            fixed (Point* point = points)
            {
                *point = new Point();// 左下
                point->X = x + TrapezoidWidth - ShapePadding;
                point->Y = y + TrapezoidWidth - ShapePadding;

                Point* point1 = point + 1;
                *point1 = new Point();
                point1->X = x + width - TrapezoidWidth + ShapePadding;
                point1->Y = y + TrapezoidWidth - ShapePadding;

                Point* point2 = point1 + 1;
                *point2 = new Point();
                point2->X = x + width - ShapePadding;
                point2->Y = y + ShapePadding;

                Point * point3 = point2 + 1;
                *point3 = new Point();
                point3->X = x + ShapePadding;
                point3->Y = y + ShapePadding;

                Rectangle rectangle = new Rectangle(point3->X, point3->Y, point2->X - point3->X, point1->Y - point3->Y);
                using (LinearGradientBrush brush = new LinearGradientBrush(rectangle, TetrisShapeColor.OuterColor, TetrisShapeColor.UpperTrapezoidColor, LinearGradientMode.Vertical))
                {
                    g.FillPolygon(brush, points);
                }
            }
            // 下
            Point[] points2 = new Point[4];
            fixed (Point* point = points2)
            {
                *point=new Point();
                point->X = x + ShapePadding;
                point->Y = y + height - ShapePadding;

                Point* point1 = point + 1;
                *point1 = new Point();
                point1->X = x + width - ShapePadding;
                point1->Y = y + height - ShapePadding;

                Point* point2 = point1 + 1;
                *point2 = new Point();
                point2->X = x + width - TrapezoidWidth + ShapePadding;
                point2->Y = y + height - TrapezoidWidth + ShapePadding;

                Point* point3 = point2 + 1;
                *point3 = new Point();
                point3->X = x + TrapezoidWidth - ShapePadding;
                point3->Y = y + height - TrapezoidWidth + ShapePadding;

                //points2[0] = new Point(x + ShapePadding, y + height - ShapePadding);
                //points2[1] = new Point(x + width - ShapePadding, y + height - ShapePadding);
                //points2[2] = new Point(x + width - TrapezoidWidth + ShapePadding, y + height - TrapezoidWidth + ShapePadding);
                //points2[3] = new Point(x + TrapezoidWidth - ShapePadding, y + height - TrapezoidWidth + ShapePadding);
                //Rectangle rectangle2 = new Rectangle(points2[3].X, points2[3].Y, points2[2].X - points2[3].X, points2[1].Y - points2[3].Y);
                Rectangle rectangle2 = new Rectangle(point3->X, point3->Y, point2->X - point3->X, point1->Y - point2->Y);
                using (LinearGradientBrush brush = new LinearGradientBrush(rectangle2, TetrisShapeColor.UnderTrapezoidColor, TetrisShapeColor.OuterColor, LinearGradientMode.Vertical))
                {
                    g.FillPolygon(brush, points2);
                }
            }
               
            // 左
            Point[] points3 = new Point[4];
            fixed (Point* point = points3)
            {
                *point = new Point();
                point->X = x + ShapePadding;
                point->Y = y + height - ShapePadding;

                Point* point1 = point + 1;
                *point1 = new Point();
                point1->X = x + TrapezoidWidth - ShapePadding;
                point1->Y = y + height - TrapezoidWidth + ShapePadding;

                Point* point2 = point1 + 1;
                *point2 = new Point();
                point2->X = x + TrapezoidWidth - ShapePadding;
                point2->Y = y + TrapezoidWidth - ShapePadding;

                Point* point3 = point2 + 1;
                *point3 = new Point();
                point3->X = x + ShapePadding;
                point3->Y = y + ShapePadding;

                //points3[0] = new Point(x + ShapePadding, y + height - ShapePadding);
                //points3[1] = new Point(x + TrapezoidWidth - ShapePadding, y + height - TrapezoidWidth + ShapePadding);
                //points3[2] = new Point(x + TrapezoidWidth - ShapePadding, y + TrapezoidWidth - ShapePadding);
                //points3[3] = new Point(x + ShapePadding, y + ShapePadding);

                //Rectangle rectangle3 = new Rectangle(points3[3].X, points3[3].Y, points3[2].X - points3[3].X, points3[1].Y - points3[3].Y);
                Rectangle rectangle3 = new Rectangle(point3->X, point3->Y, point2->X - point3->X, point1->Y - point3->Y);
                using (LinearGradientBrush brush = new LinearGradientBrush(rectangle3, TetrisShapeColor.OuterColor, TetrisShapeColor.LeftTrapezoidColor, LinearGradientMode.Horizontal))
                {
                    g.FillPolygon(brush, points3);
                }
            }

             // 右
                Point[] points4 = new Point[4];
            fixed (Point* point = points4)
            {
                *point = new Point();
                point->X = x + width - TrapezoidWidth + ShapePadding;
                point->Y = y + height - TrapezoidWidth + ShapePadding;

                Point* point1 = point + 1;
                *point1 = new Point();
                point1->X = x + width - ShapePadding;
                point1->Y = y + height - ShapePadding;

                Point* point2 = point1 + 1;
                *point2 = new Point();
                point2->X = x + width - ShapePadding;
                point2->Y = y + ShapePadding;

                Point* point3 = point2 + 1;
                *point3 = new Point();
                point3->X = x + width - TrapezoidWidth + ShapePadding;
                point3->Y = y + TrapezoidWidth - ShapePadding;

                //points4[0] = new Point(x + width - TrapezoidWidth + ShapePadding, y + height - TrapezoidWidth + ShapePadding);
                //points4[1] = new Point(x + width - ShapePadding, y + height - ShapePadding);
                //points4[2] = new Point(x + width - ShapePadding, y + ShapePadding);
                //points4[3] = new Point(x + width - TrapezoidWidth + ShapePadding, y + TrapezoidWidth - ShapePadding);

                //Rectangle rectangle4 = new Rectangle(points4[3].X, points4[3].Y, points4[2].X - points4[3].X, points4[1].Y - points4[3].Y);
                Rectangle rectangle4 = new Rectangle(point3->X, point3->Y, point2->X - point3->X, point1->Y - point3->Y);
                using (LinearGradientBrush brush = new LinearGradientBrush(rectangle4, TetrisShapeColor.RightTrapezoidColor, TetrisShapeColor.OuterColor, LinearGradientMode.Horizontal))
                {
                    g.FillPolygon(brush, points4);
                }
            }

           

            // 内正方形
            Rectangle rect2 = new Rectangle(x + TrapezoidWidth, y + TrapezoidWidth, width - TrapezoidWidth - TrapezoidWidth, height - TrapezoidWidth - TrapezoidWidth);
            using SolidBrush brush2 = new SolidBrush(TetrisShapeColor.InnerColor);
            g.FillRectangle(brush2, rect2);
        }

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
}
